package com.example.test01;
//vers 1.0
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

@SuppressLint("NewApi")
public class MainActivity extends Activity
{

	int value;
	Camera mCamera;

	Camera.PreviewCallback prewCallBack;

	public class trio
	{
		int r, g, b;

		public trio()
		{
			r = 0;
			g = 0;
			b = 0;
		}

		public trio(int x, int y, int z)
		{
			r = x;
			g = y;
			b = z;
		}
	}

	trio[][] bitMatr;
	int[][] shapeMatr;
	int x = 0;

	public int verify(trio a, trio b, int i, int j)
	{
		if (Math.abs(a.b - b.b) < 18 && Math.abs(a.g - b.g) < 18
				&& Math.abs(a.r - b.r) < 18 && shapeMatr[i][j] == 0)
		{

			return 1;
		}

		return 0;
	}

	public class point
	{
		int x, y;

		public point(int a, int b)
		{
			x = a;
			y = b;
		}
	}

	int[] hash;

	public void fill(int i, int j)
	{
		ArrayList<point> queue = new ArrayList<point>();
		queue.add(new point(i, j));
		hash[x] = 1;

		while (queue.isEmpty() == false)
		{
			int n = queue.get(0).x;
			int m = queue.get(0).y;
			shapeMatr[n][m] = x;

			if (n + 1 != bitMatr.length
					&& verify(bitMatr[n][m], bitMatr[n + 1][m], n + 1, m) == 1)
			{
				queue.add(new point(n + 1, m));
				shapeMatr[n + 1][m] = x;
				hash[x]++;
			}

			if (n + 1 != bitMatr.length
					&& m != 0
					&& verify(bitMatr[n][m], bitMatr[n + 1][m - 1], n + 1,
							m - 1) == 1)
			{
				queue.add(new point(n + 1, m - 1));
				shapeMatr[n + 1][m - 1] = x;
				hash[x]++;
			}

			if (m + 1 != bitMatr[0].length
					&& n + 1 != bitMatr.length
					&& verify(bitMatr[n][m], bitMatr[n + 1][m + 1], n + 1,
							m + 1) == 1)
			{
				queue.add(new point(n + 1, m + 1));
				shapeMatr[n + 1][m + 1] = x;
				hash[x]++;
			}

			if (m + 1 != bitMatr[0].length
					&& verify(bitMatr[n][m], bitMatr[n][m + 1], n, m + 1) == 1)
			{
				queue.add(new point(n, m + 1));
				shapeMatr[n][m + 1] = x;
				hash[x]++;
			}

			if (m != 0
					&& verify(bitMatr[n][m], bitMatr[n][m - 1], n, m - 1) == 1)
			{
				queue.add(new point(n, m - 1));
				shapeMatr[n][m - 1] = x;
				hash[x]++;
			}

			if (m != 0
					&& n != 0
					&& verify(bitMatr[n][m], bitMatr[n - 1][m - 1], n - 1,
							m - 1) == 1)
			{
				queue.add(new point(n - 1, m - 1));
				shapeMatr[n - 1][m - 1] = x;
				hash[x]++;
			}

			if (n != 0
					&& verify(bitMatr[n][m], bitMatr[n - 1][m], n - 1, m) == 1)
			{
				queue.add(new point(n - 1, m));
				shapeMatr[n - 1][m] = x;
				hash[x]++;
			}

			if (n != 0
					&& m + 1 != bitMatr[0].length
					&& verify(bitMatr[n][m], bitMatr[n - 1][m + 1], n - 1,
							m + 1) == 1)
			{
				queue.add(new point(n - 1, m + 1));
				shapeMatr[n - 1][m + 1] = x;
				hash[x]++;
			}

			queue.remove(0);

		}

	}

	public int apel()
	{
		shapeMatr = new int[bitMatr.length][bitMatr[0].length];

		for (int i = 0; i < shapeMatr.length; i++)
			for (int j = 0; j < shapeMatr[0].length; j++)
				shapeMatr[i][j] = 0;

		System.out.println(x);

		hash = new int[90000];

		for (int i = 0; i < bitMatr.length; i++)
			for (int j = 0; j < bitMatr[0].length; j++)
				if (shapeMatr[i][j] == 0)
				{
					x++;
					fill(i, j);
				}

		System.out.println(x);
		int max = 0;
		value = 0;
		for (int i = 1; hash[i] != 0; i++)
		{
			System.out.println(i + " " + hash[i]);
			if (max < hash[i])
			{
				max = hash[i];
				value = i;
			}
		}
		// System.out.println(value);
		return value;
	}

	int resursa = R.raw.h;
	int dataBufferSize = 460800;
	int maxVolume;
	float curentVolume;

	public int getRes(String culoare)
	{
		if (culoare.equalsIgnoreCase("rosu"))
			return R.raw.a;
		else if (culoare.equalsIgnoreCase("albastru"))
			return R.raw.b;
		else if (culoare.equalsIgnoreCase("portocaliu"))
			return R.raw.c;
		else if (culoare.equalsIgnoreCase("turcoaz"))
			return R.raw.d;
		else if (culoare.equalsIgnoreCase("galben"))
			return R.raw.e;
		else if (culoare.equalsIgnoreCase("verde"))
			return R.raw.f;
		else if (culoare.equalsIgnoreCase("mov"))
			return R.raw.g;
		else
			return R.raw.h;
	}

	public Bitmap getResizedBitmap(Bitmap bm)
	{
		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int newHeight = displaymetrics.heightPixels;
		int newWidth = displaymetrics.widthPixels;

		int width = bm.getWidth();

		int height = bm.getHeight();

		float scaleWidth = ((float) newWidth) / width;

		float scaleHeight = ((float) newHeight) / height;

		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map

		matrix.postScale(scaleWidth, scaleHeight);
		// matrix.postRotate(90);
		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
				matrix, false);

		return resizedBitmap;

	}

	public String HueToCuloare(int hue, int sat, int bright)
	{
		String cul = "";

		int dist = (int) Math.sqrt((100 - sat) * (100 - sat) + (100 - bright)
				* (100 - bright));

		if (dist < 90)
		{
			if (hue >= 347 && hue <= 360 || hue <= 2)
			{
				cul = "rosu";
			}
			else if (hue <= 346 && hue >= 258)
			{
				cul = "mov";
			}
			else if (hue <= 257 && hue >= 208)
			{
				cul = "albastru";
			}
			else if (hue <= 207 && hue >= 161)
			{
				cul = "turcoaz";
			}
			else if (hue <= 160 && hue >= 69)
			{
				cul = "verde";
			}
			else if (hue <= 68 && hue >= 40)
			{
				cul = "galben";
			}
			else if (hue <= 39 && hue >= 3)
			{
				cul = "portocaliu";
			}
		}
		else
			cul = "gray";

		return cul;
	}

	Bitmap bm;
	Vibrator vibrator;
	int perioada = 0;
	int timp_ramas = 0;
	int timp_trecut = 0;
	boolean vibreaza = false;
	ImageView img1;
	CountDownTimer tm;
	int contor = 5;

	private static ColorMatrix getContrast(float contrast)
	{
		ColorMatrix cm = new ColorMatrix();
		float scale = contrast + 1.f;
		float translate = (-.5f * scale + .5f) * 255.f;
		cm.set(new float[]
		{ scale, 0, 0, 0, translate, 0, scale, 0, 0, translate, 0, 0, scale, 0,
				translate, 0, 0, 0, 1, 0 });
		return cm;
	}

	public Bitmap setContrast(Bitmap bmpOriginal)
	{
		int width, height;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();

		Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
				Bitmap.Config.RGB_565);
		Canvas c = new Canvas(bmpGrayscale);
		Paint paint = new Paint();
		ColorMatrix cm = getContrast(3);
		// float[] fl = cm.getArray();

		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);
		c.drawBitmap(bmpOriginal, 0, 0, paint);
		return bmpGrayscale;
		// return bmpOriginal;
	}

	public Bitmap toGrayscale(Bitmap bmpOriginal)
	{
		int width, height;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();

		Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
				Bitmap.Config.RGB_565);
		Canvas c = new Canvas(bmpGrayscale);
		Paint paint = new Paint();
		ColorMatrix cm = new ColorMatrix();
		cm.setSaturation(0);
		float[] fl = cm.getArray();

		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);
		c.drawBitmap(bmpOriginal, 0, 0, paint);
		return bmpGrayscale;
		// return bmpOriginal;
	}

	Bitmap bitmap, bitmapGray;

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		if (requestCode == 100 && resultCode == Activity.RESULT_OK)
		{
			// We need to recyle unused bitmaps
			if (bitmap != null)
			{
				bitmap.recycle();
			}
			// InputStream stream = getContentResolver().openInputStream(
			// data.getData());
			bitmap = (Bitmap) data.getExtras().get("data");

			// stream.close();

			bm = getResizedBitmap(bitmap);

			tm.start();

			// img1.setImageBitmap(toGrayscale(bm));
			img1.setImageBitmap(toGrayscale(setContrast(bm)));
			bitmapGray = toGrayscale(setContrast(bm));

		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	MediaPlayer mp;
	int sec = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_main);
		SurfaceView s = (SurfaceView) findViewById(R.id.surfaceView1);

		int cameras_nr = 1;
		try
		{
			cameras_nr = Camera.getNumberOfCameras();
		}
		catch (Exception e)
		{
			// TODO: handle exception
		}
		if (cameras_nr == 1)
		{
			mCamera = Camera.open();
			Camera.Parameters parameters = mCamera.getParameters();
			parameters.setPreviewFrameRate(5);
			// parameters.setPreviewFpsRange(1,2);
			mCamera.setParameters(parameters);
			mCamera.addCallbackBuffer(new byte[dataBufferSize]);
		}
		else
		{
			mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
			mCamera.addCallbackBuffer(new byte[dataBufferSize]);
		}

		// dataBufferSize stands for the byte size for a picture frame
		// mCamera.addCallbackBuffer(new byte[dataBufferSize]);
		// mCamera.addCallbackBuffer(new byte[dataBufferSize]);
		// mCamera.setPreviewDisplay(videoCaptureViewHolder);
		// videoCaptureViewHolder is a SurfaceHolder object
		prewCallBack = new Camera.PreviewCallback()
		{
			private long timestamp = 0;

			public synchronized void onPreviewFrame(byte[] data, Camera camera)
			{
				System.out.println("on Preview Frame");
				contor++;
				if (contor >= 5)
				{
					contor = 0;

					Size previewSize = camera.getParameters().getPreviewSize();
					YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21,
							previewSize.width, previewSize.height, null);
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width,
							previewSize.height), 80, baos);
					byte[] jdata = baos.toByteArray();

					// Convert to Bitmap
					Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0,
							jdata.length);

					Matrix matrix = new Matrix();

					matrix.postRotate(90);

					Bitmap rotatedBitmap = Bitmap.createBitmap(bmp, 0, 0,
							bmp.getWidth(), bmp.getHeight(), matrix, true);

					bm = getResizedBitmap(rotatedBitmap);

					img1.setImageBitmap(toGrayscale(setContrast(bm)));
					bitmapGray = toGrayscale(setContrast(bm));

					/*
					 * bm=setContrast(bm); bitMatr=new
					 * trio[bm.getWidth()][bm.getHeight()]; for(int
					 * i=0;i<bm.getWidth();i++) for(int
					 * j=0;j<bm.getHeight();j++) { int color=bm.getPixel(i,j);
					 * float red= (color >> 16) & 0xFF; float green= (color >>
					 * 8) & 0xFF; float blue= (color >> 0) & 0xFF;
					 * bitMatr[i][j]=new trio((int) red,(int) green, (int)
					 * blue);
					 * 
					 * }
					 */

					// apel();

					// Bitmap bitmap2 = BitmapFactory.decodeByteArray(data, 0,
					// data.length);

					// do picture data process
				}
				camera.addCallbackBuffer(data);

			}
		};

		// mCamera.startPreview();

		SurfaceHolder h = s.getHolder();
		h.addCallback(new Callback()
		{

			@Override
			public void surfaceDestroyed(SurfaceHolder holder)
			{
				// TODO Auto-generated method stub

			}

			@Override
			public void surfaceCreated(SurfaceHolder holder)
			{
				System.out.println("surface created");
				Camera.Parameters parameters = mCamera.getParameters();
				List<Camera.Size> previewSizes = parameters
						.getSupportedPreviewSizes();

				// You need to choose the most appropriate previewSize for your
				// app
				Camera.Size previewSize = previewSizes.get(1);
				parameters
						.setPreviewSize(previewSize.width, previewSize.height);
				mCamera.setParameters(parameters);
				try
				{
					mCamera.setPreviewDisplay(holder);
				}
				catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				mCamera.setPreviewCallback(prewCallBack);
				mCamera.startPreview();

			}

			@Override
			public void surfaceChanged(SurfaceHolder holder, int format,
					int width, int height)
			{
				// TODO Auto-generated method stub

			}
		});
		img1 = (ImageView) findViewById(R.id.imageView1);
		img1.setOnTouchListener(new OnTouchListener()
		{

			@Override
			public boolean onTouch(View v, MotionEvent e)
			{
				if (e.getX() < bm.getWidth() && e.getY() < bm.getHeight())
				{
					System.out.println("Click la x=" + e.getX() + " y="
							+ e.getY());
					int color = bm.getPixel((int) e.getX(), (int) e.getY());

					int colorGray = bitmapGray.getPixel((int) e.getX(),
							(int) e.getY());
					float redGray = (colorGray >> 16) & 0xFF;
					float greenGray = (colorGray >> 8) & 0xFF;
					float blueGray = (colorGray >> 0) & 0xFF;
					float red = (color >> 16) & 0xFF;
					float green = (color >> 8) & 0xFF;
					float blue = (color >> 0) & 0xFF;
					curentVolume = ((red + green + blue) / 765 * maxVolume);
					System.out.println("volum din rgb: " + curentVolume);
					float[] hsv = new float[3];
					Color.RGBToHSV((int) red, (int) green, (int) blue, hsv);
					System.out.println("red=" + red + " green=" + green
							+ " blue=" + blue);
					System.out.println(hsv[0] + " -- " + hsv[1] + " -- "
							+ hsv[2]);
					resursa = getRes(HueToCuloare((int) hsv[0],
							(int) (hsv[1] * 100), (int) (hsv[2] * 100)));
					System.out.println(HueToCuloare((int) hsv[0],
							(int) (hsv[1] * 100), (int) (hsv[2] * 100)));
					float medie = (redGray + greenGray + blueGray) / 3;
					/*
					 * if(shapeMatr[(int)e.getX()][(int)e.getY()]==value)
					 * perioada=0; else perioada=100;
					 */
					perioada = 1 + (int) ((255 - medie) * 2);
				}

				if (e.getAction() == MotionEvent.ACTION_UP)
					perioada = 0;
				return true;
			}
		});
		Intent intent = new Intent(
				android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		// intent.setType("image/*");
		// intent.setAction(Intent.ACTION_GET_CONTENT);
		// intent.addCategory(Intent.CATEGORY_OPENABLE);
		// startActivityForResult(intent, 100);

		AudioManager amanager = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		maxVolume = amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
		mp = new MediaPlayer();

		vibrator = (Vibrator) getSystemService(this.VIBRATOR_SERVICE);

		tm = new CountDownTimer(999999, 25)
		{

			@Override
			public void onTick(long millisUntilFinished)
			{

				if (perioada > 0)
				{
					if (sec == 0)
					{
						mp.reset();
						try
						{
							AssetFileDescriptor afd = MainActivity.this
									.getResources().openRawResourceFd(resursa);

							mp.setDataSource(afd.getFileDescriptor(),
									afd.getStartOffset(), afd.getLength());
							System.out.println("curent: " + curentVolume);
							mp.setVolume(curentVolume, curentVolume);
							afd.close();
							mp.prepare();
						}
						catch (IllegalArgumentException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						catch (IllegalStateException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						catch (IOException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

						mp.start();

					}
					sec += 25;
					if (sec > 500)
						sec = 0;
					timp_trecut += 25;

					if (timp_trecut > perioada)
					{
						timp_trecut = 0;
						if (vibreaza)
						{
							vibrator.cancel();
							vibreaza = false;
						}
						else
						{
							vibrator.vibrate(perioada);
							vibreaza = true;
						}
					}
				}
				else
					vibrator.cancel();
			}

			@Override
			public void onFinish()
			{
				// TODO Auto-generated method stub

			}
		};
		tm.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}
